package zh.dummy.netty.client.handler;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.ScheduledFuture;
import zh.dummy.netty.client.util.NettyMessageBuilder;
import zh.dummy.netty.core.protocol.MessageType;
import zh.dummy.netty.core.protocol.NettyMessage;

public class HeartBeatReqHandler extends ChannelHandlerAdapter{
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private volatile ScheduledFuture<?> heartBeat;
	
	public void channelRead(ChannelHandlerContext ctx,Object msg){
		NettyMessage message = (NettyMessage) msg;
		//握手成功，主动发送心跳消息
		if(message.getHeader() != null
				&& message.getHeader().getType() == MessageType.LOGIN_RESP.value()){
			if(logger.isDebugEnabled()){
				logger.debug("start heartbeat");
			}
			heartBeat = ctx.executor().scheduleAtFixedRate(
					new HeartBeatReqHandler.HeartBeatTask(ctx), 0, 5000, TimeUnit.MILLISECONDS);
		}else if(message.getHeader() != null
				&& message.getHeader().getType() == MessageType.HEARTBEAT_RESP.value()){
			if(logger.isDebugEnabled()){
				logger.debug("received heartbeat response");
			}
		}else{
			ctx.fireChannelRead(msg);
		}
	}
	
	private class HeartBeatTask implements Runnable{
		private final ChannelHandlerContext ctx;
		public HeartBeatTask(final ChannelHandlerContext ctx){
			this.ctx = ctx;
		}
		
		public void run() {
			NettyMessage heatBeat = NettyMessageBuilder.buildHeatBeatReq();
			ctx.writeAndFlush(heatBeat);
			if(logger.isDebugEnabled()){
				logger.debug("send heartbeat request");
			}
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause){
		if(heartBeat != null){
			heartBeat.cancel(true);
			heartBeat = null;
		}
		ctx.fireExceptionCaught(cause);
	}
}
